#pragma once
#include "log.hpp"
#include <sys/types.h>
#include <sys/socket.h>
#include <cstring>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string>
#include <strings.h>
#include <fcntl.h>
#include <unistd.h>
#include <wait.h>
#include <signal.h>

class tcpServer
{
public:
    class threadData
    {
    public:
        threadData(int socketfd, const string &userIp, uint16_t userPort, tcpServer *ptr)
            : _socketfd(socketfd), _userIp(userIp), _userPort(userPort), _ptr(ptr)
        {
        }

    public:
        int _socketfd;
        string _userIp;
        uint16_t _userPort;
        tcpServer *_ptr;
    };

    tcpServer(uint16_t port = 10000, string ip = "0.0.0.0")
        : _ip(ip), _port(port)
    {
        init();
    }
    ~tcpServer()
    {
    }
    void init()
    {
        // socket
        _socketListen = socket(AF_INET, SOCK_STREAM, 0);
        if (_socketListen == -1)
        {
            log(ERROR, "socket create fail");
            cout << "errno: " << errno << " " << strerror(errno);
            exit(-1);
        }
        log(NOTICE, "socket suceess !");

        // 下面的代码用来让服务器重启不需要等待时间，暂时不知道原理，先用着
        int opt = 1;
        setsockopt(_socketListen, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt));

        // bind
        sockaddr_in local;
        local.sin_family = AF_INET;
        local.sin_port = htons(_port);
        int ret_pton = inet_pton(AF_INET, _ip.c_str(), &local.sin_addr);
        if (ret_pton == -1)
        {
            log(ERROR, "inet_pton fail");
            exit(-1);
        }
        int ret_bind = bind(_socketListen, (sockaddr *)&local, sizeof(local));
        if (ret_bind == -1)
        {
            log(ERROR, "bind fail");
            cout << "errno: " << errno << " " << strerror(errno);
            exit(-1);
        }
        log(NOTICE, "bind suceess !");

        // listen
        int ret_listen = listen(_socketListen, 2); // 第二个参数底层流的大小不要设置的太大
        if (ret_listen == -1)
        {
            log(ERROR, "listen fail");
            exit(-1);
        }
        log(NOTICE, "listen suceess !");
    }


    void run()
    {
        while (true)
        {
            sleep(1);//不进行任何操作，不accept
        }
    }

private:
    int _socketListen;
    uint16_t _port;
    string _ip;
};
